home *** CD-ROM | disk | FTP | other *** search
- // ************************************************************
- //
- // System-Click Notification Icon
- // Win95 32-bit Shell Extension
- // James P. Ketrenos
- //
- // ************************************************************
- #include <afx.h>
- #include <shlobj.h> // SHAddToRecentDocs()
- // NOTE: I had to comment out line 139 in OAIDL.H in order to get it to compile with shlobj.h.
- // The line commented out redefined BSTR
-
- #include "Resource.h"
- #include "Global.h"
- #include "IconWnd.h"
-
-
-
- // ************************************************************
- // CIconWnd Class Implementation
- //
- // Purpose:
- // * Respond to Notification Button actions.
- // * Respond to WM_WININICHANGE messages to keep tool-tip
- // up to date.
- // * Keep the system INI and registry up to date with all
- // the latest values as we change them.
- // ************************************************************
-
- BEGIN_MESSAGE_MAP(CIconWnd, CFrameWnd)
- ON_COMMAND(IDC_FULLDRAG, OnFullDrag)
- ON_COMMAND(IDC_ANIMATED, OnAnimated)
- ON_COMMAND(IDC_CLRDOCS, OnClearDocs)
- ON_COMMAND(IDC_ABOUT, OnAbout)
- ON_COMMAND(IDC_APPHELP, OnHelp)
- ON_COMMAND(IDCLOSE, OnClose)
- ON_MESSAGE(SC_WM_NOTIFYICON, OnNotifyIcon)
- ON_WM_DESTROY()
- ON_WM_TIMER()
- ON_WM_WININICHANGE()
- END_MESSAGE_MAP()
-
-
-
- // ************************************************************
- // Message-Mapped Functions
- // ************************************************************
-
-
-
- // *******************************
- // CIconWnd::OnWinIniChange()
- //
- // Purpose:
- // * Respond to the system WM_WININICHANGE message
- // * If the [Windows] section has been altered, re-fetch
- // our settings from the system and update our variables.
- // * Update the Notification Icon accordingly
- // *******************************
- void CIconWnd::OnWinIniChange(LPCTSTR lpszSection)
- {
- CString String = "WINDOWS";
-
- if (!String.CompareNoCase(lpszSection))
- {
- m_Fetch();
-
- m_UpdateIconTip();
-
- // Check to see if Windows Extension #1 is installed
- m_bExtension1 = SystemParametersInfo(SPI_GETWINDOWSEXTENSION, 1, 0, 0);
- }
-
- }
-
-
-
- // *******************************
- // CIconWnd::OnAbout()
- //
- // Purpose:
- // * Check to see if our About window is already up.
- // + If so, make the current one the foreground active window
- // + If not, create the About window and display it.
- // *******************************
- void CIconWnd::OnAbout()
- {
- CWnd* pWnd = FindWindow(NULL, "About System-Click . . .");
-
- if (!pWnd)
- {
- CDialog About(IDD_ABOUT, this);
-
- About.DoModal();
- }
- else
- pWnd->SetForegroundWindow();
- }
-
-
-
- // *******************************
- // CIconWnd::OnHelp()
- //
- // Purpose:
- // * Check to see if our Help window is already up.
- // + If so, make the current one the foreground active window
- // + If not, create the Help window and display it.
- // *******************************
- void CIconWnd::OnHelp()
- {
- CWnd* pWnd = FindWindow(NULL, "System-Click Help");
-
- if (!pWnd)
- {
- CDialog Help(IDD_HELP, this);
-
- Help.DoModal();
- }
- else
- pWnd->SetForegroundWindow();
- }
-
-
- // *******************************
- // CIconWnd::OnClearDocs()
- //
- // Purpose:
- // * Clears the Recent Document list in the Start Menus
- // *******************************
- void CIconWnd::OnClearDocs()
- {
- // Clears the document list
- ::SHAddToRecentDocs(NULL, NULL);//SHARD_PATH, NULL); //SHARD_PIDL, NULL);
- }
-
-
- // *******************************
- // CIconWnd::OnAnimated()
- //
- // Purpose:
- // * Toggle the Animated Window flag
- // * Update the Notification Icon Tool-Tip to reflect current state
- // * Update the Win95 system parameters
- // *******************************
- void CIconWnd::OnAnimated()
- {
- ANIMATIONINFO Animated;
-
- m_bAnimated = (m_bAnimated ? FALSE : TRUE);
-
- m_UpdateIconTip();
-
- // Update the system parameter, save the setting in the Windows INI file, and let
- // all top level windows know we have changed a system parameter.
- Animated.cbSize = sizeof(ANIMATIONINFO);
- Animated.iMinAnimate = m_bAnimated;
-
- SystemParametersInfo(
- SPI_SETANIMATION,
- 0,
- &Animated,
- SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
- }
-
-
-
- // *******************************
- // CIconWnd::OnFullDrag()
- //
- // Purpose:
- // * Toggle the Full Dragging flag
- // * Update the Notification Icon Tool-Tip to reflect current state
- // * Update the Win95 system parameters
- // *******************************
- void CIconWnd::OnFullDrag()
- {
- m_bFullDrag = (m_bFullDrag ? FALSE : TRUE);
-
- m_UpdateIconTip();
-
- // Update the system parameter, save the setting in the Windows INI file, and let
- // all top level windows know we have changed a system parameter.
- SystemParametersInfo(
- SPI_SETDRAGFULLWINDOWS,
- m_bFullDrag,
- 0,
- SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
- }
-
-
-
- // ************************************************************
- // General Class Functions
- // ************************************************************
-
-
-
- // *******************************
- // CIconWnd::CIconWnd()
- //
- // Purpose:
- // * Place keeper
- // *******************************
- CIconWnd::CIconWnd()
- {
- }
-
-
-
- // *******************************
- // CIconWnd::~CIconWnd()
- //
- // Purpose:
- // * Place keeper
- // *******************************
- CIconWnd::~CIconWnd()
- {
- }
-
-
-
- // *******************************
- // CIconWnd::m_UpdateIconTip()
- //
- // Purpose:
- // * Updates the Notification Icon Tool-Tip to refelct
- // current variable states.
- // *******************************
- void CIconWnd::m_UpdateIconTip()
- {
- NOTIFYICONDATA nidSysClk;
-
- nidSysClk.cbSize = sizeof(NOTIFYICONDATA);
- nidSysClk.hWnd = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
- nidSysClk.uID = IDI_SYSCLK;
- nidSysClk.uFlags = NIF_TIP;
- wsprintf(
- nidSysClk.szTip,
- "FD: %s AW: %s",
- m_bFullDrag ? "ON" : "OFF",
- m_bAnimated ? "ON" : "OFF");
-
- Shell_NotifyIcon(NIM_MODIFY, &nidSysClk);
- }
-
-
-
- // *******************************
- // CIconWnd::m_Fetch()
- //
- // Purpose:
- // * Fetch system settings from Win95
- // *******************************
- void CIconWnd::m_Fetch()
- {
- ANIMATIONINFO Animated;
-
- SystemParametersInfo(
- SPI_GETDRAGFULLWINDOWS,
- 0,
- &m_bFullDrag,
- 0);
-
- Animated.cbSize = sizeof(ANIMATIONINFO);
- SystemParametersInfo(
- SPI_GETANIMATION,
- 0,
- &Animated,
- 0);
- m_bAnimated = Animated.iMinAnimate ? TRUE : FALSE;
- }
-
-
-
- // *******************************
- // CIconWnd::OnTimer()
- //
- // Purpose:
- // * Called .5 seconds after the Notification Icon is activated
- // * Provide functionality for Notification Icon
- // * Keeps stray mouse button clicks from dismissing menu before
- // it has displayed.
- // *******************************
- void CIconWnd::OnTimer(UINT nIDEvent)
- {
- if (nIDEvent == IDT_CLOSE)
- {
- SendMessage(WM_CLOSE);
- }
-
- if (nIDEvent == IDT_POPUP)
- {
- CMenu hPopup;
- POINT Point;
- HWND hOrigActive;
-
- // Kill the timer
- KillTimer(m_Timer);
- m_Timer = 0;
-
- // Create our menu
- hPopup.CreatePopupMenu();
-
- if (m_bExtension1) // Requires Extension1 Pack to be installed
- hPopup.AppendMenu(MF_STRING, IDC_FULLDRAG, "&Full Drag");
-
- // Standard Win95 functionality
- hPopup.AppendMenu(MF_STRING, IDC_ANIMATED, "&Animated Windows");
- hPopup.AppendMenu(MF_STRING, IDC_CLRDOCS, "&Clear Recent Doc List");
-
- // Generic program menu items
- hPopup.AppendMenu(MF_SEPARATOR);
- hPopup.AppendMenu(MF_STRING, IDC_ABOUT, "A&bout . . .");
- hPopup.AppendMenu(MF_STRING, IDC_APPHELP, "&Help");
- //hPopup.AppendMenu(MF_STRING, IDCLOSE, "E&xit");
-
- // Set the initial checks correctly
- hPopup.CheckMenuItem(IDC_ANIMATED, MF_BYCOMMAND | (m_bAnimated ? MF_CHECKED : MF_UNCHECKED));
-
- if (m_bExtension1)
- hPopup.CheckMenuItem(IDC_FULLDRAG, MF_BYCOMMAND | (m_bFullDrag ? MF_CHECKED : MF_UNCHECKED));
-
- // Get the currently active window, set our window to active, pop up the menu, and
- // then return the system state to the way it was.
-
- hOrigActive = ::GetForegroundWindow();
- SetForegroundWindow();
- ::GetCursorPos(&Point);
- hPopup.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, Point.x, Point.y, this, NULL);
- ::SetForegroundWindow(hOrigActive);
-
- // Destroy our menu to insure our resources are freed
- hPopup.DestroyMenu();
-
- return;
- }
- }
-
-
-
- // *******************************
- // CIconWnd::OnNotifyIcon()
- //
- // Purpose:
- // * Notification Icon callback function
- // * If the user left clicks on the icon, pop up the toggle button window.
- // * If the user double-clicks on the icon, toggle the current mode.
- //
- // NOTE: Because of the magic in Win95, it is better not to do any actual
- // processing immediately after we encounter our message from the
- // Notification Icon.
- //
- // It is better to trigger a Timer and respond to the WM_TIMER message.
- // This gives the system enough time to flush out the stray mouse
- // messages before our code actually takes place.
- //
- // It appears as if the OS gives our program the mouse messages first, and
- // then hands them to the Taskbar after we take them. If we do not wait
- // and immediately do a TrackPopupMenu(), the stray mouse clicks may
- // dismiss this menu. Likewise, if we close the application immediately,
- // the mouse clicks that triggered our app to shutdown will be fed to
- // the task bar and may cause adverse effects.
- // *******************************
- LONG CIconWnd::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
- {
- UINT uID;
- UINT uMsg;
- BOOL bFDOriginal = m_bFullDrag;
- BOOL bAWOriginal = m_bAnimated;
-
- uID = (UINT)wParam;
- uMsg = (UINT)lParam;
-
- if ((uMsg == WM_RBUTTONDBLCLK) && (uID == IDI_SYSCLK))
- {
- m_Timer = SetTimer(IDT_CLOSE, 500, NULL);
-
- return 0L;
- }
-
- if ((uMsg == WM_LBUTTONDOWN) && (uID == IDI_SYSCLK))
- {
- m_Timer = SetTimer(IDT_POPUP, 500, NULL);
-
- return 0L;
- }
-
- return 0L;
- }
-
-
-
- // *******************************
- // CIconWnd::m_InitIcon()
- //
- // Purpose:
- // * Fetch the Full-Drag option from our INI file
- // * Initialize the Notification Icon
- // * Set the SystemParameterInfo() setting for the Full Dragging
- // accordingly.
- // Returns:
- // TRUE Success
- // FALSE Failure, either from Shell_NotifyIcon
- // *******************************
- BOOL CIconWnd::m_InitIcon()
- {
- NOTIFYICONDATA nidSysClk;
- BOOL bRetVal;
- HICON hIcon;
- ANIMATIONINFO Animated;
-
- // Fetch entries from our INI file [defaults = FALSE]
- // NOTE: We don't do this since all our settings are saved in the
- // windows INI and in the registry.
- //m_bFullDrag = AfxGetApp()->GetProfileInt("General", "Full Drag", 0);
- //m_bAnimated = AfxGetApp()->GetProfileInt("General", "Animated", 0);
-
- // Fetch current values from the System settings
- m_Fetch();
-
- // Latch the Notification Icon into the Notification Area
- hIcon = AfxGetApp()->LoadIcon(MAKEINTRESOURCE(IDI_SYSCLK));
-
- nidSysClk.cbSize = sizeof(NOTIFYICONDATA);
- nidSysClk.hWnd = GetSafeHwnd();
- nidSysClk.uID = IDI_SYSCLK;
- nidSysClk.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
- nidSysClk.uCallbackMessage = SC_WM_NOTIFYICON;
- nidSysClk.hIcon = hIcon;
- wsprintf(
- nidSysClk.szTip,
- "FD: %s AW: %s",
- m_bFullDrag ? "ON" : "OFF",
- m_bAnimated ? "ON" : "OFF");
-
- bRetVal = Shell_NotifyIcon(NIM_ADD, &nidSysClk);
-
- if (hIcon)
- DestroyIcon(hIcon);
-
- // Update the system parameter, save the setting in the Windows INI file, and let
- // all top level windows know we have changed a system parameter.
- SystemParametersInfo(
- SPI_SETDRAGFULLWINDOWS,
- m_bFullDrag,
- 0,
- SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
-
- Animated.cbSize = sizeof(ANIMATIONINFO);
- Animated.iMinAnimate = m_bAnimated;
-
- SystemParametersInfo(
- SPI_SETANIMATION,
- 0,
- &Animated,
- SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
-
- return bRetVal;
- }
-
-
-
- // *******************************
- // CIconWnd::OnDestroy()
- //
- // Purpose:
- // * Delete the notification icon from the Notification area.
- // * Save the System-Click setting to our INI setting.
- //
- // *******************************
- void CIconWnd::OnDestroy()
- {
- NOTIFYICONDATA nidSysClk;
-
- // Verify that we do not have a timer allocated
- if (m_Timer)
- {
- KillTimer(m_Timer);
- m_Timer = 0;
- }
-
- // Remove the Notification Icon from the Notification area
- nidSysClk.cbSize = sizeof(NOTIFYICONDATA);
- nidSysClk.hWnd = GetSafeHwnd();
- nidSysClk.uID = IDI_SYSCLK;
-
- Shell_NotifyIcon(NIM_DELETE, &nidSysClk);
-
- // Save our setting to the INI file
- // NOTE: We don't do this since all our settings are saved in the
- // windows INI and in the registry.
- //AfxGetApp()->WriteProfileInt("General", "SysClk", m_bFullDrag);
- //AfxGetApp()->WriteProfileInt("General", "Animated", m_bAnimated);
-
- CWnd::OnDestroy();
- }
-